package openbang.account.service.impl;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.logging.Logger;

import javax.jdo.JDOObjectNotFoundException;
import javax.jdo.PersistenceManager;
import javax.jdo.Query;

import openbang.account.service.entity.MsgAsyn;
import openbang.account.service.entity.MsgReceive;
import openbang.account.service.entity.UserAccount;
import openbang.account.service.exception.SecurityOBException;
import openbang.account.service.intf.MsgService;
import openbang.account.service.util.PMF;
import openbang.account.service.util.SecurityRemoteServiceServlet;
import openbang.account.service.util.SessionHelper;
import openbang.account.service.vo.MsgServiceEnum;
import openbang.account.service.vo.MsgStatusEnum;
import openbang.account.service.vo.UserLoginInfo;

/**
 * 消息服务
 * 要求必须登录
 * @author aibo zeng
 *
 */

@SuppressWarnings("serial")
public class MsgServiceImpl  extends SecurityRemoteServiceServlet implements MsgService{
	private static final Logger log = Logger.getLogger(MsgServiceImpl.class.getName());
	
	/**
	 * 获取消息
	 * @param msgStatus  两种：非存档 存档
	 * @param pageNo
	 * @param pageCount
	 * @return
	 */
	public List<MsgReceive> getListMsg(int msgStatus , int pageNo,int pageCount) throws SecurityOBException {
		log.warning("come in getListMsg  msgStatus="+msgStatus);
		SessionHelper.updUserLoginInfo(getThreadLocalRequest());
		List<MsgReceive> msgReceiveRet = new ArrayList<MsgReceive>();
		
		PersistenceManager pm = PMF.get().getPersistenceManager();
		UserLoginInfo userInfo = SessionHelper.getUserLoginInfo(getThreadLocalRequest());
		Query q = pm.newQuery(MsgReceive.class);
		//查出 非删除的、是否存档的
		if(msgStatus==MsgStatusEnum.HAS_ARCHIVE.getCode()){
		   q.setFilter("receiverId == user_id && readStatus == "+MsgStatusEnum.HAS_ARCHIVE.getCode());
		}
		else{
		   q.setFilter("receiverId == user_id && ( readStatus == "+MsgStatusEnum.PENDING_READ.getCode()+" || readStatus== "+MsgStatusEnum.HAS_READ.getCode()+" )");			
		}
		// 排序字段,如果查询对一个属性指定了不等过滤条件并对其他属性指定了排序顺序，则使用不等过滤条件的属性必须在其他属性之前排序
		q.setOrdering("updTime desc");
		
		q.declareParameters("java.lang.Long user_id");
		q.setRange((pageNo-1)*pageCount, pageNo*pageCount-1);

		Collection<MsgReceive> msgReceives = (Collection<MsgReceive>) q.execute(userInfo.getId());
		
		if(msgReceives!=null && msgReceives.size()>0){
			for(MsgReceive msgR : msgReceives){
				//如何带出  MsgAsyn 对象 --- GAE JDO 不支持 join ，不支持预加载					
				msgR.setMsgAsyn(getMsgAsyn(msgR.getMsgId(),pm));
				//冗余旧数据
				if(msgR.getMsgAsyn().getSendTime()==null){
					msgR.getMsgAsyn().setSendTime(new Date());
					msgR.getMsgAsyn().setUpdTime(new Date());
				}
				msgReceiveRet.add(msgR);
			}
		}
		pm.close();
		
		log.warning("end. count="+msgReceives.size());
		return msgReceiveRet;
	}

	@Override
	public List<MsgReceive> getArchiveListMsg(int pageNo, int pageCount)
			throws SecurityOBException {
		return getListMsg(MsgStatusEnum.HAS_ARCHIVE.getCode(),pageNo,pageCount);
	}

	@Override
	public List<MsgReceive> getReceiveListMsg(int pageNo,int pageCount)  throws SecurityOBException{
		log.warning("come in getReceiveListMsg ");
		//收件箱，不包含存档的
		return getListMsg(MsgStatusEnum.HAS_READ.getCode(),pageNo,pageCount);
	}
	
	/**
	 * 
	 * @param id 发生消息ID
	 * @param pm
	 * @return
	 */
	public MsgAsyn getMsgAsyn(Long id , PersistenceManager pm){
		MsgAsyn msg = null;
		try{
			msg = pm.getObjectById(MsgAsyn.class,id);
		}catch(JDOObjectNotFoundException jdoe){			
		}
		return msg;
	}

	/**
	 * 
	 * @param id 接收消息ID
	 * @param pm
	 * @return
	 */
	public MsgReceive getMsgReceive(Long id , PersistenceManager pm){
		MsgReceive msg = null;
		try{
			msg = pm.getObjectById(MsgReceive.class,id);
		}catch(JDOObjectNotFoundException jdoe){			
		}
		return msg;
	}
	
	@Override
	public Integer sendMsg(MsgAsyn msg, String[] receivers)  throws SecurityOBException{
		log.warning("come in sendMsg ");
		UserLoginInfo userInfo = SessionHelper.getUserLoginInfo(getThreadLocalRequest());
		//界面传入的 msg 只有标题和内容
		msg.setId(null);
		msg.setSenderEmail(userInfo.getEmail());
		msg.setSenderId(userInfo.getId());
		AccountServiceImpl accountService = new AccountServiceImpl();
		PersistenceManager pm = PMF.get().getPersistenceManager();
		pm.makePersistent(msg);
		for(String receEmail : receivers){
			UserAccount receUser = accountService.findByEmail(receEmail,pm);
			if(receUser!=null){
				MsgReceive msgRece = new MsgReceive();
				msgRece.setMsgId(msg.getId());				
				msgRece.setReceiverEmail(receUser.getEmail());
				msgRece.setReceiverId(receUser.getId());
				pm.makePersistent(msgRece);
			}
			else{
				log.warning("收件人地址不存在 email="+receEmail);
			}
		}
		//pm.makePersistentAll(arg0);
		pm.close();
		SessionHelper.updUserLoginInfo(getThreadLocalRequest());
		return MsgServiceEnum.OK.getCode();
	}

	@Override
	public Integer archiveMsg(Long[] msgId) throws SecurityOBException {
		UserLoginInfo userInfo = SessionHelper.getUserLoginInfo(getThreadLocalRequest());
		PersistenceManager pm = PMF.get().getPersistenceManager();
		for(Long id : msgId){
			//最优是直接更改状态
			MsgReceive msg = getMsgReceive(id,pm);
			if(msg==null){
				continue;
			}
			//应该判断 消息是否属于 session的 登录人 
			if(msg.getReceiverId()!=userInfo.getId()){
				//非法归档
				continue;
			}
			msg.setReadStatus(MsgStatusEnum.HAS_ARCHIVE.getCode());
			msg.setUpdTime(new Date());
		}
		pm.close();
		SessionHelper.updUserLoginInfo(getThreadLocalRequest());
		return MsgServiceEnum.OK.getCode();		
	}

	@Override
	public Integer deleteMsg(Long[] msgId)  throws SecurityOBException{
		UserLoginInfo userInfo = SessionHelper.getUserLoginInfo(getThreadLocalRequest());
		PersistenceManager pm = PMF.get().getPersistenceManager();
		for(Long id : msgId){
			//最优是直接更改状态
			MsgReceive msg = getMsgReceive(id, pm);
			if(msg==null){
				continue;
			}
			if(msg.getReceiverId()!=userInfo.getId()){
				//非法删除
				continue;
			}
			pm.deletePersistent(msg);
		}
		pm.close();
		SessionHelper.updUserLoginInfo(getThreadLocalRequest());
		return MsgServiceEnum.OK.getCode();		
	}
	
	/**
	 * 统计消息总数
	 * @param msgStatus  两种：非存档 存档
	 * @return
	 */
	public Integer countMsg(int msgStatus){
		Integer counts = 0;
		log.warning("come in countMsg  msgStatus="+msgStatus);
		PersistenceManager pm = PMF.get().getPersistenceManager();
		UserLoginInfo userInfo = SessionHelper.getUserLoginInfo(getThreadLocalRequest());
		Query q = pm.newQuery(MsgReceive.class);
		//查出 非删除的、是否存档的
		if(msgStatus==MsgStatusEnum.HAS_ARCHIVE.getCode()){
		   q.setFilter("receiverId == user_id && readStatus == "+MsgStatusEnum.HAS_ARCHIVE.getCode());
		}
		else{
		   q.setFilter("receiverId == user_id && readStatus < "+MsgStatusEnum.HAS_ARCHIVE.getCode());			
		}
		q.declareParameters("java.lang.Long user_id");

		Collection<MsgReceive> msgReceives = (Collection<MsgReceive>) q.execute(userInfo.getId());
		
		if(msgReceives!=null){
			counts = msgReceives.size();
		}
		else{			
		}
		pm.close();
		return counts;		
	}
	
	@Override
	public Integer countArchiveMsg() throws SecurityOBException {
		return countMsg(MsgStatusEnum.HAS_ARCHIVE.getCode());
	}

	@Override
	public Integer countReceiveMsg() throws SecurityOBException {
		return countMsg(MsgStatusEnum.HAS_READ.getCode());
	}

	@Override
	public Integer doSetReadMsg(Long msgId) throws SecurityOBException {
		PersistenceManager pm = PMF.get().getPersistenceManager();
		MsgReceive msg = getMsgReceive(msgId, pm);
		if(msg==null){
			pm.close();
			return MsgServiceEnum.NOEXIST.getCode();
		}
		else{
			msg.setReadStatus(MsgStatusEnum.HAS_READ.getCode());
			msg.setReadTime(new Date());
		}
		pm.close();
		SessionHelper.updUserLoginInfo(getThreadLocalRequest());
		return MsgServiceEnum.OK.getCode();
	}

	
}
